package com.stormrage.shiro.realm;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.stormrage.entity.shiro.ShiroAcct;
import com.stormrage.edu.serv.shiro.ShiroServ;

/**
 * @author www.stormragetech.com
 * @date 2016年1月19日
 * @version 1.0.0
 */
public class UserRealm extends AuthorizingRealm {

	private static final Logger logger = LoggerFactory.getLogger(UserRealm.class);

	@Autowired
	private ShiroServ shiroServ;

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();

		try {
			String acct = (String) principals.getPrimaryPrincipal();
			ShiroAcct entity = shiroServ.queryAcctByAcct(acct);

			logger.debug(" 用户的ID为 " + entity.getId());

			if (entity.getRole().equals(0)) // 超管
				authorizationInfo.setStringPermissions(shiroServ.queryPermSet());
			if (entity.getRole().equals(1))
				authorizationInfo.setStringPermissions(shiroServ.queryPermSetById(entity.getId()));

		} catch (Exception e) {
			return null;
		}

		return authorizationInfo;

	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

		String acct = (String) token.getPrincipal();

		ShiroAcct entity = null;
		try {

			entity = shiroServ.queryAcctByAcct(acct);

		} catch (Exception e) {
			return null;
		}

		if (null == entity) {
			throw new UnknownAccountException();// 没找到帐号
		}

		if (entity.getLocked().equals(1)) {
			throw new LockedAccountException(); // 帐号锁定
		}

		logger.debug(" 用户信息为 " + entity.toString());
		logger.debug(" 用户getSign为 " + entity.getSign());

		// 交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配，如果觉得人家的不好可以自定义实现
		SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(entity.getAcct(), // 用户名
				entity.getPass(), // 密码
				ByteSource.Util.bytes(entity.getSign()), // salt=username+salt
				getName() // realm name
		);

		logger.debug(" 1 验证结果为 " + entity.getPass());
		logger.debug(" 2 验证结果为 " + authenticationInfo.getCredentials().toString());

		return authenticationInfo;
	}

	@Override
	public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
		super.clearCachedAuthorizationInfo(principals);
	}

	@Override
	public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
		super.clearCachedAuthenticationInfo(principals);
	}

	@Override
	public void clearCache(PrincipalCollection principals) {
		super.clearCache(principals);
	}

	public void clearAllCachedAuthorizationInfo() {
		getAuthorizationCache().clear();
	}

	public void clearAllCachedAuthenticationInfo() {
		getAuthenticationCache().clear();
	}

	public void clearAllCache() {
		clearAllCachedAuthenticationInfo();
		clearAllCachedAuthorizationInfo();
	}

}